In this project, we find the maximum height reached by a cart that travels along a catenary-shaped suspension bridge. The cart is acted upon by an external force, which governs the maximum height reached by the cart. The cart comes to a rest when the component of the mass parallel to the incline is equal to the external force. We will use the Newton-Raphson Method to write a computer program that finds this equilibrium position.
The shape of the bridge is goverend by the constant $a$. The smaller the constant $a$, the "steeper" the graph, therefore representing a bridge with supension cables that are longer and less taught. A value of $a$ that is negative produces an upside-down graph, thus no longer representing a bridge, so for our representation of this problem, $a>0$.
As $a$ depends on various properties of the bridge, we will assume that anyone using this program to find an equilibirium position already knows the value of $a$ for the bridge, as well as the bridges length. Assuming that there are towers of equal height at either end of the bridge , the height of these towers can be calculated using $a$ and the length. $$height = a \cosh \left(\frac{length}{2a}\right)$$
If the force applied to the cart is greater than the weight of the cart, $mg$, the cart is guaranteed to reach the top of the bridge. This is because, no matter how steep the bridge gets, no component of weight would ever be greater than or equal to the force applied.
In this model, friction is ignored. While the cart will experience friction, and friction is a requirement for the cart to come to a rest (rather than moving beyond the equilibrium point due to its velocity), it does not experience any friction when it does come to a stop, as it is no longer moving, and the friction that brought it to a stop is no longer acting upon it.
This model is a static model, as it solves for a single equilibrium position, and it is deterministic as the solution is only dependent on the intial conditions, such as the mass of the cart, the force applied to it, and the steepness of the bridge. The equilibrium position is a continuous variable, as it can fall anywhere in a range of $x$ values equal to the length of the bridge. To initialize the problem we will need to specify the mass and force applied to the cart, as well as the steepnes constant $a$ and the length of the bridge. We will also need to specify the tolerance (the tolerance in the error of our final solution) and the initial guess for the solution.
When using the Newton-Raphson Method to solve this equation, diveregence is very likely, depending on the initial guess, and overflow errors in the hyperblolic functions occurr very quickly. To ensure that the algorithm does not diverege, we will check that the change in $x$ gets smaller with each iteration, ensuring that the $x$ value is getting closer to the root, rather than further away. This will be done by creating a new variable that stores the previous $dx$ value, and then comparing the absolute values of the previous $dx$ value and the current $dx$ value, starting in the second iteration (the first iteration does not have a previous dx to compare to).
The cart will be modelled as point mass, as we can assume that the cart is much smaller than the suspension bridge it is travelling on, and any deformation to the bridge's cable due to the cart will be negligible. The path the cart travels along on the bridge is modelled by a catenary, mathematically represented by the hyperbolic cosine, with its steepness governed by the constant $a$. The cart will be modelled travelling in the positive x direction. $$ y = a \cosh \left(\frac{x}{a}\right)$$
The gradient at any point $x$ can be found by differentiating the function. $$ \frac{dy}{dx} = \sinh \left(\frac{x}{a}\right) $$
The angle between the tangent to the curve and the $ x $ axis is defined $ \theta $. The value of $ \tan(\theta) $ is equal to the change in $y$ divided by the change in $x$, so we find that $$ \tan(\theta) =\sinh \left(\frac{x}{a}\right).$$
As the cart travels along this catenray path, the component of the weight that is parallel to the path is $mg\sin(\theta)$. A constant force $F$ is also exerted upon the cart. The resultant force on the cart can be calculated as $$ F_{tot} = F - mg\sin(\theta).$$
$$ \tan(\theta) =\sinh \left(\frac{x}{a}\right)=k$$$$ k^2=\frac{\sin^2(\theta)}{1-\sin^2(\theta)}$$$$ \sin^2(\theta)=\frac{k^2}{1+k^2}$$$$ \sin(\theta)=\frac{k}{\sqrt{1+k^2}}=\frac{\sinh\left(\frac{x}{a}\right)}{\sqrt{1+\sinh^2\left(\frac{x}{a}\right)}}$$$$ F_{tot} = F - mg\left(\frac{\sinh\left(\frac{x}{a}\right)}{\sqrt{1+\sinh^2\left(\frac{x}{a}\right)}}\right)$$Theoretically the cart should come to a stop when the total force acting on it is 0. This occurrs when the component of the weight that is tangent to the catenary is equal to the external force acting upon the cart. This equilibrium point is represented by the root of the equation $y = F - mg\sin(\theta)$. Here, $x=0$ represents the minimum of the cateneray, and the starting position of the cart. There should be two equilibrium positions, one in the negative $x$ direction, nd one in the positive $x$ direction. However, these points are exact opposites ($x$ and $-x$), so we will focus on finding the positive x root. The Newton-Raphson formula will be used to find this root.
This root finds the $x$ position of the equilibrium point. This $x$ value will be subsituted back into the formula for the catenary to find the $y$ posisition for the catenary, and so the height at which the cart comes to a stop. This height will then be compared to the bridges overall height, allowing us to determine if the cart can reach the top of the bridge, or id it comes to a rest at a certain height somewhere along the path of the bridge.
import numpy as np
#initial conditions
force = 200
mass = 50
a = 900
length=1000 #total length of bridge, with the cart starting from length/2 at the center of the bridge
height = a*np.cosh(length/(2*a))-a #this is the maximum height of the suspension cables, calculated using bridge length and a
#initial guess
x0 =0
tolerance = 1e-5 #acceptable error in the solution
root = False
# exception checks
Error = 0 #we will use the Error variable to keep track of any errors that occur
if a<=0:
print("Error: the value of a must be greater than 0. Values of less than 0 produce an inverted bridge shape.")
Error = 1
elif mass<0:
print("Error: Mass must be greater than or equal to 0.")
elif length<0:
print("Error: Length of bridge must be greater than or equal to 0.")
Error = 1
elif force<0:
print("Error: force must be greater than or equal to 0.")
Error = 1
elif x0>length/2 or x0<0:
print("Error: the initial guess of the solution must lie within the length of the bridge.")
Error = 1
else:
print('All initial conditions are met. A solution exists.')
All initial conditions are met. A solution exists.
if Error == 1:
print("Enter different initial conditions.")
elif force>mass*9.81:
print("The cart will reach the top of the bridge, as the weight of the cart is not great enough to bring it to a stop.")
else:
x = x0 #initial value for the start of the loop
n=0 #will be used to count number of iterations
dx = 10 #initialisation of dx, will be recalculated in first loop
dxPrev = 0 #initialisation of previous dx variable, will be used to save dx of the previous loop
while(np.absolute(dx)>tolerance):
n=n+1
dxPrev = dx
F = force - mass*9.81*np.sinh(x/a)/(1+np.sinh(x/a)**2)**0.5
G=-mass*9.81*np.cosh(x/a)/(a*((np.sinh(x/a)**2)+1)**1.5)
if G==0: #ensures that the program never divides by 0
print("Error: G cannot equal 0")
break
dx = -F/G
if n>1: #only starts checking for convergence once the loop has run once and there is a previous dx to compare with
if np.absolute(dx)>np.absolute(dxPrev):
break
x = x+dx
if np.absolute(dx)>np.absolute(dxPrev):
print("Diverging. Try a different initial guess.")
else:
print("The x position reached by the cart is ", x)
root = True #variable used to track if a root to the equation has been found
The x position reached by the cart is 389.61557845082143
if root:
if x>=length/2: #the cart has come to a stop at a point that is higher than the height of the bridge
print("The cart can reach the top of the bridge.")
else:
y = a*np.cosh(x/a)-a #calculates height of the cart
print("The cart does not reach the top, and stops at a height of", y)
else:
print("No root to the equation found.")
The cart does not reach the top, and stops at a height of 85.65881741505405
One way of verifying the model is testing it for some initial conditions for which the result is known. We will test some easily verifyable expected solutions, by changing the initial conditions to specific values.
If we solve this problem analytically, we should get the same answer as the answer provided by the algorithm.
$$ F(x)=F-mg\sin(\theta)=0$$$$ F=mg\sin(\theta)$$$$ \tan(\theta) = \frac{d}{dx}\left(a\cosh\left(\frac{x}{a}\right)\right)$$$$ \tan(\theta)=\sinh\left(\frac{x}{a}\right)$$$$ \theta = \tan^{-1}\left(\sinh\left(\frac{x}{a}\right)\right)$$$$ F=mg\sin\left(\tan^{-1}\left(\sinh\left(\frac{x}{a}\right)\right)\right)$$$$ x=a\sinh^{-1}\left(\tan\left(\sin^{-1}\left(\frac{F}{mg}\right)\right)\right)$$For the initial conditions:
We get the result $x=717.6736023$, which is within the tolerance from the result of the Newton-Raphson algorithm, which calculated $x = 717.6736022$.
Our group also came up with a second algorithm, allowing us to confirm the Newton-Raphson algorithm generates a correct output. The alternative algorithm is the bisection algorithm, that divides the range in which the solution can lie into two, and checks if the solution lies in the lower half of the range or in the upper half. It will then use the half as the new range, and keep repeating the process untill the range is smaller than the error tolerance of the result. The midpoint of this range is then taken as the result.
import numpy as np
force = 200
mass = 50
a = 900 #steepeness of function (changable parameter)
length = 1000 #(changable parameter)
minx = 0.00 #bottom of the bridge, starting point
maxx = length/2 #the highest point of the bridge, so the farthest point at which a solution can exist
height = a*np.cosh((length)/a) - a
Tolerance = 1e-5
midx = (maxx + minx)/2 #between starting and ending point
difference = maxx-minx
while (difference > Tolerance):
midx = (maxx + minx)/2
difference = maxx-minx
F = force - mass*9.81*np.sinh(midx/a) * (1+np.sinh(midx/a)**2)**(-1/2) #evaluates function at midx
if F > 0.0: #solution must be in upper half of range
minx = midx
if F < 0.0: #solution must be inlower half or range
maxx = midx
y = a*np.cosh((midx)/a) - a
print ("The cart stops at x=", midx, "at height", y)
The cart stops at x= 389.61557671427727 at height 85.65881663959135
Eventhough this code has not been tested as thouroughly as the Newton-Raphson Method above, it does produce the same result as the Newton-Raphson Method for the above initial conditions, suggesting that both algorithms are finding the correct solution. Bisection solution = 85.6588166, Newton-Raphson solution = 85.6588174
Having implemented the code, tested for all imaginable exceptions, and verified the result in a variety of ways, we can conclude that our code outputs the correct result for the point along a catenary-shaped bridge at which a cart comes to a rest. This result can be applied to the real world. For an example, if a cart is used to repaint a bridge, this program allows us to calculate if the cart can paint the whole bridge, or if it will come to a stop somewhere along it.